Skip to content

Add hidden --plan-mode flag to bundle plan and deploy#5680

Draft
denik wants to merge 23 commits into
mainfrom
denik/local-only
Draft

Add hidden --plan-mode flag to bundle plan and deploy#5680
denik wants to merge 23 commits into
mainfrom
denik/local-only

Conversation

@denik

@denik denik commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Adds a hidden --plan-mode flag to bundle plan and bundle deploy (direct engine only). Values: full (default), local, and offline (reserved — rejected at parse time until implemented). --plan-mode=local skips the per-resource remote read at plan time and defers all remote-status-dependent work at apply time.

PlanEntry state fields (direct engine):

  • PriorState (new) — last saved local state, StateType. Populated in every mode. Consumers that need state-shaped data (prior grants principals, prior etag) read this via RemoteOrPrior(adapter).
  • RemoteState (existing) — a fresh remote read, RemoteType. Nil in --plan-mode=local. Consumers that need live-remote-only fields (cluster.State, app.ComputeStatus, model_id) read this; the reasonable behavior on nil is to skip whatever depends on live status.

\${resources...} references still resolve: .id and other config fields come from local state, and a reference to a remote-only field (e.g. \${resources.jobs.bar.creator_user_name}) fetches that one target on demand in local mode. Direct engine only; rejected with an actionable error on terraform.

Apply-time behavior in --plan-mode=local:

  • Cluster / sql_warehouse: DoUpdate skips the lifecycle Start/Stop when entry.RemoteState is nil; WaitAfterUpdate skips its poll for the same reason. The next full-mode deploy applies the real transition.
  • App: manageLifecycle is skipped entirely when entry.RemoteState is nil.
  • Grants: removedGrantPrincipals reads from PriorState when RemoteState is nil, so config that removes a principal correctly revokes it.
  • Model: model_id is remote-only; same-run downstream refs to \${resources.models.foo.model_id} resolve to empty in local mode (documented limitation, same shape as any remote-only reference).

Tests:

  • acceptance/bundle/local/basicplan --plan-mode=local reports no drift, issues no resource reads; .id reference resolves from local state; local_used telemetry; out-of-band rename invisible to --plan-mode=local plan; deploy --plan with a local plan warns; READPLAN matrix covers the warning.
  • acceptance/bundle/local/referencesplan --plan-mode=local fetches only the one referenced target on-demand (for a remote-only field), reports no drift, unaffected by out-of-band drift on that target; a normal plan detects the same drift.
  • acceptance/bundle/local/lifecycle-skip (new) — cluster with lifecycle.started toggle; deploy --plan-mode=local issues zero /clusters requests; the following full-mode deploy applies the real transition.
  • acceptance/bundle/local/grants-remove (new) — schema grants with a principal removed from config; deploy --plan-mode=local correctly revokes the removed principal.
  • acceptance/bundle/local/rejected — terraform rejects the flag; unknown values and offline are rejected at parse time.
  • no_drift invariant gains a LOCAL_DIFF matrix that runs every config with and without --plan-mode=local.
  • acceptance/bundle/resources--plan-mode=local matrix added to catalogs, external_locations, jobs/num_workers, schemas/update, volumes/change-name for smoke coverage.
  • All full-mode out.plan.*.json outputs regenerated to include the new prior_state field alongside remote_state.

This pull request and its description were written by Isaac.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/acceptance/bundle/ - needs approval

36 files changed
Suggested: @andrewnester
Also eligible: @janniklasrose, @pietern, @shreyas-goenka, @lennartkats-db, @anton-107

/bundle/ - needs approval

10 files changed
Suggested: @andrewnester
Also eligible: @janniklasrose, @pietern, @shreyas-goenka, @lennartkats-db, @anton-107

/cmd/bundle/ - needs approval

4 files changed
Suggested: @andrewnester
Also eligible: @janniklasrose, @pietern, @shreyas-goenka, @lennartkats-db, @anton-107

Any maintainer (@andrewnester, @anton-107, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db, @janniklasrose, @lennartkats-db) can approve all areas.
See OWNERS for ownership rules.

@denik
denik force-pushed the denik/local-only branch from 6a2e7c1 to ce803e6 Compare June 23, 2026 12:31
@denik
denik temporarily deployed to test-trigger-is June 23, 2026 12:31 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is June 23, 2026 12:31 — with GitHub Actions Inactive
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: b856d28

Run: 29848606568

Env 🟨​KNOWN 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 314 1050 5:31
💚​ aws windows 4 4 316 1048 5:21
💚​ azure linux 4 4 314 1049 6:39
💚​ azure windows 4 4 316 1047 5:02
🟨​ gcp linux 3 1 4 313 1051 10:38
🟨​ gcp windows 3 1 4 315 1049 8:50
8 interesting tests: 4 SKIP, 3 KNOWN, 1 RECOVERED
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 🟨​K 🟨​K
🟨​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R 🟨​K 🟨​K
🟨​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R 🟨​K 🟨​K
Top 4 slowest tests (at least 2 minutes):
duration env testname
3:58 aws windows TestAccept
3:27 azure windows TestAccept
3:06 gcp windows TestAccept
2:01 gcp windows TestAccept/bundle/deploy/mlops-stacks/DATABRICKS_BUNDLE_ENGINE=terraform

@denik
denik force-pushed the denik/local-only branch from ce803e6 to d4eb28b Compare June 23, 2026 15:10
@denik
denik temporarily deployed to test-trigger-is June 23, 2026 15:10 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is June 23, 2026 15:10 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is June 24, 2026 05:04 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is June 24, 2026 05:04 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is June 24, 2026 05:28 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is June 24, 2026 05:28 — with GitHub Actions Inactive
bradleyjamrozik-origindigital pushed a commit to Origin-Digital-LLC/databricks-cli that referenced this pull request Jun 25, 2026
…e if resize failed due to INVALID_STATE (databricks#5716)

## Changes

`DoResize` now tries `clusters/resize` first and falls back to
`clusters/edit` (via `DoUpdate`) on `INVALID_STATE`. `PlanEntry` is
threaded through to `DoResize` so the fallback reuses the existing
edit+retry logic without duplication.

## Why

A saved plan records the action at plan time (e.g. `resize` when the
cluster was running). If the cluster terminates before the plan is
applied, the resize API returns `INVALID_STATE` and the deploy fails.
The fallback makes apply resilient to this race.

This also helps for local-only plan
(databricks#5680) where we don't have remote
state available to check. With this change we can always plan 'resize'
based on changed attributes.

## Tests

New acceptance test `resize-terminated-fallback`: plans while the
cluster is running (plan shows `resize`), terminates the cluster,
applies the saved plan, and confirms both a failed resize request and a
successful edit fallback in the request log.

_This PR was written by Claude Code._
@denik
denik force-pushed the denik/local-only branch from 9b4c606 to 3abb966 Compare July 3, 2026 12:22
@denik
denik temporarily deployed to test-trigger-is July 3, 2026 12:22 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 3, 2026 12:22 — with GitHub Actions Inactive
@denik
denik force-pushed the denik/local-only branch from 3abb966 to e03533c Compare July 6, 2026 09:41
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 09:42 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 09:42 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 09:53 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 09:53 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 10:56 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 10:56 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 11:31 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 11:31 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 11:57 — with GitHub Actions Inactive
@denik
denik had a problem deploying to test-trigger-is July 6, 2026 11:57 — with GitHub Actions Failure
@denik
denik had a problem deploying to test-trigger-is July 6, 2026 13:45 — with GitHub Actions Failure
@denik
denik temporarily deployed to test-trigger-is July 6, 2026 13:45 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 13, 2026 16:57 — with GitHub Actions Inactive
@denik
denik temporarily deployed to test-trigger-is July 13, 2026 16:57 — with GitHub Actions Inactive
@denik
denik force-pushed the denik/local-only branch from b6bc472 to 151bc11 Compare July 20, 2026 08:44
@denik
denik marked this pull request as draft July 20, 2026 08:51
@denik denik changed the title direct: Add hidden --local flag to bundle plan and deploy Add hidden --plan-mode flag to bundle plan and deploy Jul 21, 2026
@denik
denik force-pushed the denik/local-only branch from 1f7967a to db23f8a Compare July 21, 2026 14:39
denik added 22 commits July 22, 2026 10:56
When passed, the plan is computed from the local state only: the per-resource
remote read is skipped, so the remote state of resources is neither fetched nor
considered. References that genuinely need a target's remote state (e.g. a
remote-only field) fetch that target on demand, so $resources references still
resolve. Direct engine only; rejected on terraform.

Exercise it in the no_drift invariant via a LOCAL_DIFF matrix.

Co-authored-by: Isaac
When --local resolves a reference that needs a target's remote-only field, it
already fetches that target on demand. Copy those fetched states onto their plan
entries (entry.RemoteState) so the plan shows what was actually read. Done in a
single-threaded pass after the parallel walk: during the walk a target is fetched
from a dependent's goroutine under the target's read lock, where writing its entry
would race with sibling dependents.

Co-authored-by: Isaac
Add a LOCAL=["", "--local"] matrix to three resource tests (jobs/num_workers,
schemas/update, volumes/change-name) so plan/deploy run both with and without
--local. Deploy issues the same mutating requests either way (only GET reads
differ, which print_requests.py excludes), so output is identical across variants.
--local is excluded on terraform (rejected there) and not applied to `bundle plan
-o json`, whose remote_state would diverge.

Co-authored-by: Isaac
A --local plan is computed without remote state, so a saved plan can miss
out-of-band drift. Add a top-level local_only field (omitempty, so normal plans
are unchanged) and warn when deploy --plan applies a local-only plan.

Extend local/basic to record the JSON plan, showing local_only: true and the
absence of remote_state.

Co-authored-by: Isaac
Drop the redundant b.localOnly field (remoteStateForRef reads b.Plan.LocalOnly,
set before the walk), remove a dead nil-guard in the post-walk reconciliation
loop (entries are always nil there in --local mode), and trim a duplicated
comment. No behavior change.

Also regenerate no_drift/out.test.toml for the merged LOCAL_DIFF matrix.

Co-authored-by: Isaac
Tested commit: 6b94feb7d acc: regenerate no_drift/out.test.toml with LOCAL_DIFF matrix entry

<!-- Acceptance tests: 6 (2 added, 4 modified) — 6 regression -->

| test | branch | main (de465e09b) | latest (v1.6.0) |
| --- | --- | --- | --- |
| TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct | ✅ | ❌ | ❌ |
| TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=catalog.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=catalog.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=catalog.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=catalog.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=dashboard.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=dashboard.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_job_cluster.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_job_cluster.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_job_cluster.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_job_cluster.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_task_cluster.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_task_cluster.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_task_cluster.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_task_cluster.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_for_each_task.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_for_each_task.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_for_each_task.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_apply_policy_default_values_for_each_task.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=experiment.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=experiment.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=experiment.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=experiment.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=external_location.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=external_location.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=external_location.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=external_location.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=genie_space.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=genie_space.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_1000_tasks.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_1000_tasks.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_1000_tasks.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_1000_tasks.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_cross_resource_ref.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_cross_resource_ref.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_cross_resource_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_cross_resource_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_permission_ref.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_permission_ref.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_permission_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_permission_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_run_job_ref.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_run_job_ref.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_run_job_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_run_job_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_depends_on.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_depends_on.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_depends_on.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_depends_on.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_task.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_task.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_task.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_with_task.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_with_permissions.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_with_permissions.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_with_permissions.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_with_permissions.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_serving_endpoint.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_serving_endpoint.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_serving_endpoint.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=model_serving_endpoint.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_apply_policy_default_values.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_config_dots.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_config_dots.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_config_dots.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=pipeline_config_dots.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_branch.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_branch.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_branch.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_branch.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_catalog.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_catalog.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_catalog.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_catalog.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_database.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_database.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_database.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_database.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_endpoint.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_endpoint.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_endpoint.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_endpoint.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_project.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_project.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_project.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_project.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_role.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_role.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_role.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_role.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_synced_table.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_synced_table.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_synced_table.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=postgres_synced_table.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=registered_model.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=registered_model.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=registered_model.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=registered_model.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_grant_ref.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_grant_ref.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_grant_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_grant_ref.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope_default_backend_type.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope_default_backend_type.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope_default_backend_type.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=secret_scope_default_backend_type.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=sql_warehouse.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=sql_warehouse.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=sql_warehouse.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=sql_warehouse.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=vector_search_index.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=vector_search_index.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_external.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_external.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_external.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_external.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_uppercase_name.yml.tmpl/LOCAL_DIFF=/READPLAN= | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_uppercase_name.yml.tmpl/LOCAL_DIFF=/READPLAN=1 | ✅ | ✅ | ✅ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_uppercase_name.yml.tmpl/LOCAL_DIFF=--local/READPLAN= | ✅ | ❌ | ❌ |
| TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=volume_uppercase_name.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 | ✅ | ❌ | ❌ |
| TestAccept/bundle/resources/jobs/num_workers/DATABRICKS_BUNDLE_ENGINE=terraform/LOCAL= | ✅ | ✅ | ✅ |
| TestAccept/bundle/resources/jobs/num_workers/DATABRICKS_BUNDLE_ENGINE=direct/LOCAL= | ✅ | ✅ | ✅ |
| TestAccept/bundle/resources/jobs/num_workers/DATABRICKS_BUNDLE_ENGINE=direct/LOCAL=--local | ✅ | ❌ | ❌ |
| TestAccept/bundle/resources/schemas/update/DATABRICKS_BUNDLE_ENGINE=terraform/LOCAL= | ✅ | ✅ | ✅ |
| TestAccept/bundle/resources/schemas/update/DATABRICKS_BUNDLE_ENGINE=direct/LOCAL= | ✅ | ✅ | ✅ |
| TestAccept/bundle/resources/schemas/update/DATABRICKS_BUNDLE_ENGINE=direct/LOCAL=--local | ✅ | ❌ | ❌ |
| TestAccept/bundle/resources/volumes/change-name/DATABRICKS_BUNDLE_ENGINE=terraform/LOCAL= | ✅ | ✅ | ❌ |
| TestAccept/bundle/resources/volumes/change-name/DATABRICKS_BUNDLE_ENGINE=direct/LOCAL= | ✅ | ✅ | ❌ |
| TestAccept/bundle/resources/volumes/change-name/DATABRICKS_BUNDLE_ENGINE=direct/LOCAL=--local | ✅ | ❌ | ❌ |

<details>
<summary>TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct ✅ | main (de465e09b) ❌ | latest (v1.6.0) ❌</summary>

**main (de465e09b):**
```
=== RUN   TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct
=== PAUSE TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct
=== CONT  TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct
    acceptance_test.go:1083: Diff:
        --- bundle/local/basic/output.txt
        +++ /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundlelocalbasicDATABRICKS_BUNDLE_ENGINE=direct2985499174/001/output.txt
        @@ -6,46 +6,25 @@
         Deployment complete!

         >>> [CLI] bundle plan --local
        -Plan: 0 to add, 0 to change, 0 to delete, 2 unchanged
        +Error: unknown flag: --local

        -=== Job reads during 'bundle plan --local':
        +Usage:
        +  databricks bundle plan [flags]

        ->>> print_requests.py --get //jobs/get
        +Flags:
        +  -c, --cluster-id string   Override cluster in the deployment with the given cluster ID.
        +      --force               Force-override Git branch validation.
        +  -h, --help                help for plan
        +      --select strings      Plan only the specified resource (e.g. 'my_job' or 'jobs.my_job'). Can be repeated or comma-separated.

        -=== Plan --local as JSON:
        +Global Flags:
        +      --debug            enable debug logging
        +  -o, --output type      output type: text or json (default text)
        +  -p, --profile string   ~/.databrickscfg profile
        +  -t, --target string    bundle target to use (if applicable)
        +      --var strings      set values for variables defined in bundle config. Example: --var="foo=bar"

        ->>> [CLI] bundle plan --local -o json
        -{
        -  "plan_version": 2,
        -  "cli_version": "[DEV_VERSION]",
        -  "lineage": "[UUID]",
        -  "serial": 1,
        -  "local_only": true,
        -  "plan": {
        -    "resources.jobs.bar": {
        -      "action": "skip"
        -    },
        -    "resources.jobs.foo": {
        -      "depends_on": [
        -        {
        -          "node": "resources.jobs.bar",
        -          "label": "${resources.jobs.bar.id}"
        -        }
        -      ],
        -      "action": "skip"
        -    }
        -  }
        -}

        ->>> [CLI] bundle deploy --local
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/local-[UNIQUE_NAME]/default/files...
        -Deploying resources...
        -Updating deployment state...
        -Deployment complete!
        -
        -=== Telemetry:
        -local_used true
        -
         === Destroy
         >>> [CLI] bundle destroy --auto-approve
         The following resources will be deleted:
        @@ -56,3 +30,5 @@

         Deleting files...
         Destroy complete!
        +
        +Exit code: 1

--- FAIL: TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct (1.07s)
```

**latest (v1.6.0):**
```
=== RUN   TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct
=== PAUSE TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct
=== CONT  TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct
    acceptance_test.go:1083: Diff:
        --- bundle/local/basic/output.txt
        +++ /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundlelocalbasicDATABRICKS_BUNDLE_ENGINE=direct798157468/001/output.txt
        @@ -6,46 +6,25 @@
         Deployment complete!

         >>> [CLI] bundle plan --local
        -Plan: 0 to add, 0 to change, 0 to delete, 2 unchanged
        +Error: unknown flag: --local

        -=== Job reads during 'bundle plan --local':
        +Usage:
        +  databricks bundle plan [flags]

        ->>> print_requests.py --get //jobs/get
        +Flags:
        +  -c, --cluster-id string   Override cluster in the deployment with the given cluster ID.
        +      --force               Force-override Git branch validation.
        +  -h, --help                help for plan
        +      --select strings      Plan only the specified resource (e.g. 'my_job' or 'jobs.my_job'). Can be repeated or comma-separated.

        -=== Plan --local as JSON:
        +Global Flags:
        +      --debug            enable debug logging
        +  -o, --output type      output type: text or json (default text)
        +  -p, --profile string   ~/.databrickscfg profile
        +  -t, --target string    bundle target to use (if applicable)
        +      --var strings      set values for variables defined in bundle config. Example: --var="foo=bar"

        ->>> [CLI] bundle plan --local -o json
        -{
        -  "plan_version": 2,
        -  "cli_version": "[DEV_VERSION]",
        -  "lineage": "[UUID]",
        -  "serial": 1,
        -  "local_only": true,
        -  "plan": {
        -    "resources.jobs.bar": {
        -      "action": "skip"
        -    },
        -    "resources.jobs.foo": {
        -      "depends_on": [
        -        {
        -          "node": "resources.jobs.bar",
        -          "label": "${resources.jobs.bar.id}"
        -        }
        -      ],
        -      "action": "skip"
        -    }
        -  }
        -}

        ->>> [CLI] bundle deploy --local
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/local-[UNIQUE_NAME]/default/files...
        -Deploying resources...
        -Updating deployment state...
        -Deployment complete!
        -
        -=== Telemetry:
        -local_used true
        -
         === Destroy
         >>> [CLI] bundle destroy --auto-approve
         The following resources will be deleted:
        @@ -56,3 +30,5 @@

         Deleting files...
         Destroy complete!
        +
        +Exit code: 1

--- FAIL: TestAccept/bundle/local/basic/DATABRICKS_BUNDLE_ENGINE=direct (0.77s)
```

</details>

<details>
<summary>TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform ✅ | main (de465e09b) ❌ | latest (v1.6.0) ❌</summary>

**main (de465e09b):**
```
=== RUN   TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform
=== PAUSE TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform
=== CONT  TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform
    acceptance_test.go:1083: Diff:
        --- bundle/local/rejected/output.txt
        +++ /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundlelocalrejectedDATABRICKS_BUNDLE_ENGINE=terraf1530229415/001/output.txt
        @@ -1,12 +1,48 @@

         >>> [CLI] bundle plan --local
        -Error: --local is only supported with the direct engine. See https://docs.databricks.com/aws/en/dev-tools/bundles/direct
        +Error: unknown flag: --local

        +Usage:
        +  databricks bundle plan [flags]

        +Flags:
        +  -c, --cluster-id string   Override cluster in the deployment with the given cluster ID.
        +      --force               Force-override Git branch validation.
        +  -h, --help                help for plan
        +      --select strings      Plan only the specified resource (e.g. 'my_job' or 'jobs.my_job'). Can be repeated or comma-separated.
        +
        +Global Flags:
        +      --debug            enable debug logging
        +  -o, --output type      output type: text or json (default text)
        +  -p, --profile string   ~/.databrickscfg profile
        +  -t, --target string    bundle target to use (if applicable)
        +      --var strings      set values for variables defined in bundle config. Example: --var="foo=bar"
        +
        +
         Exit code: 1

         >>> [CLI] bundle deploy --local
        -Error: --local is only supported with the direct engine. See https://docs.databricks.com/aws/en/dev-tools/bundles/direct
        +Error: unknown flag: --local

        +Usage:
        +  databricks bundle deploy [flags]

        +Flags:
        +      --auto-approve          Skip interactive approvals that might be required for deployment.
        +  -c, --cluster-id string     Override cluster in the deployment with the given cluster ID.
        +      --fail-on-active-runs   Fail if there are running jobs or pipelines in the deployment.
        +      --force                 Force-override Git branch validation.
        +      --force-lock            Force acquisition of deployment lock.
        +  -h, --help                  help for deploy
        +      --plan string           Path to a JSON plan file to apply instead of planning (direct engine only).
        +      --select strings        Deploy only the specified resource (e.g. 'my_job' or 'jobs.my_job'). Can be repeated or comma-separated.
        +
        +Global Flags:
        +      --debug            enable debug logging
        +  -o, --output type      output type: text or json (default text)
        +  -p, --profile string   ~/.databrickscfg profile
        +  -t, --target string    bundle target to use (if applicable)
        +      --var strings      set values for variables defined in bundle config. Example: --var="foo=bar"
        +
        +
         Exit code: 1

--- FAIL: TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform (0.05s)
```

**latest (v1.6.0):**
```
=== RUN   TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform
=== PAUSE TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform
=== CONT  TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform
    acceptance_test.go:1083: Diff:
        --- bundle/local/rejected/output.txt
        +++ /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundlelocalrejectedDATABRICKS_BUNDLE_ENGINE=terraf2105928878/001/output.txt
        @@ -1,12 +1,48 @@

         >>> [CLI] bundle plan --local
        -Error: --local is only supported with the direct engine. See https://docs.databricks.com/aws/en/dev-tools/bundles/direct
        +Error: unknown flag: --local

        +Usage:
        +  databricks bundle plan [flags]

        +Flags:
        +  -c, --cluster-id string   Override cluster in the deployment with the given cluster ID.
        +      --force               Force-override Git branch validation.
        +  -h, --help                help for plan
        +      --select strings      Plan only the specified resource (e.g. 'my_job' or 'jobs.my_job'). Can be repeated or comma-separated.
        +
        +Global Flags:
        +      --debug            enable debug logging
        +  -o, --output type      output type: text or json (default text)
        +  -p, --profile string   ~/.databrickscfg profile
        +  -t, --target string    bundle target to use (if applicable)
        +      --var strings      set values for variables defined in bundle config. Example: --var="foo=bar"
        +
        +
         Exit code: 1

         >>> [CLI] bundle deploy --local
        -Error: --local is only supported with the direct engine. See https://docs.databricks.com/aws/en/dev-tools/bundles/direct
        +Error: unknown flag: --local

        +Usage:
        +  databricks bundle deploy [flags]

        +Flags:
        +      --auto-approve          Skip interactive approvals that might be required for deployment.
        +  -c, --cluster-id string     Override cluster in the deployment with the given cluster ID.
        +      --fail-on-active-runs   Fail if there are running jobs or pipelines in the deployment.
        +      --force                 Force-override Git branch validation.
        +      --force-lock            Force acquisition of deployment lock.
        +  -h, --help                  help for deploy
        +      --plan string           Path to a JSON plan file to apply instead of planning (direct engine only).
        +      --select strings        Deploy only the specified resource (e.g. 'my_job' or 'jobs.my_job'). Can be repeated or comma-separated.
        +
        +Global Flags:
        +      --debug            enable debug logging
        +  -o, --output type      output type: text or json (default text)
        +  -p, --profile string   ~/.databrickscfg profile
        +  -t, --target string    bundle target to use (if applicable)
        +      --var strings      set values for variables defined in bundle config. Example: --var="foo=bar"
        +
        +
         Exit code: 1

--- FAIL: TestAccept/bundle/local/rejected/DATABRICKS_BUNDLE_ENGINE=terraform (0.06s)
```

</details>

<details>
<summary>TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN= ✅ | main (de465e09b) ❌ | latest (v1.6.0) ❌</summary>

**main (de465e09b):**
```
=== RUN   TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== PAUSE TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== CONT  TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
    acceptance_test.go:1083:
        	Error Trace:	/Users/denis.bilenko/work/cli-trees/local-only/libs/testdiff/testdiff.go:22
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:1083
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:915
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:515
        	Error:      	Not equal:
        	            	expected: "INPUT_CONFIG_OK\n"
        	            	actual  : "INPUT_CONFIG_OK\n\nExit code: 1\n"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2 +2,3 @@

        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
        	Messages:   	bundle/invariant/no_drift/output.txt vs /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundleinvariantno_driftDATABRICKS_BUNDLE_ENGINE=di3172530878/001/output.txt
    acceptance_test.go:942:
        LOG.config: bundle:
        LOG.config:   name: test-bundle-3qcizlrz6zeqlokrmg4s54rgne
        LOG.config:
        LOG.config: resources:
        LOG.config:   alerts:
        LOG.config:     foo:
        LOG.config:       warehouse_id: 8ec9edc1-db0c-40df-af8d-7580020fe61e
        LOG.config:       display_name: test-alert-3qcizlrz6zeqlokrmg4s54rgne
        LOG.config:       file_path: ./alert.dbalert.json
        LOG.config:       permissions:
        LOG.config:         - level: CAN_MANAGE
        LOG.config:           group_name: users
    acceptance_test.go:942: LOG.cp:
    acceptance_test.go:942:
        LOG.deploy:
        LOG.deploy: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle deploy
        LOG.deploy: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/test-bundle-3qcizlrz6zeqlokrmg4s54rgne/default/files...
        LOG.deploy: Deploying resources...
        LOG.deploy: Updating deployment state...
        LOG.deploy: Deployment complete!
    acceptance_test.go:942:
        LOG.destroy:
        LOG.destroy: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle destroy --auto-approve
        LOG.destroy: The following resources will be deleted:
        LOG.destroy:   delete resources.alerts.foo
        LOG.destroy:
        LOG.destroy: All files and directories at the following location will be deleted: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-3qcizlrz6zeqlokrmg4s54rgne/default
        LOG.destroy:
        LOG.destroy: Deleting files...
        LOG.destroy: Destroy complete!
    acceptance_test.go:942: LOG.planjson:
    acceptance_test.go:942:
        LOG.validate:
        LOG.validate: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle validate
        LOG.validate: Name: test-bundle-3qcizlrz6zeqlokrmg4s54rgne
        LOG.validate: Target: default
        LOG.validate: Workspace:
        LOG.validate:   User: tester@databricks.com
        LOG.validate:   Path: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-3qcizlrz6zeqlokrmg4s54rgne/default
        LOG.validate:
        LOG.validate: Validation OK!
--- FAIL: TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN= (0.38s)
```

**latest (v1.6.0):**
```
=== RUN   TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== PAUSE TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== CONT  TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
    acceptance_test.go:1083:
        	Error Trace:	/Users/denis.bilenko/work/cli-trees/local-only/libs/testdiff/testdiff.go:22
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:1083
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:915
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:515
        	Error:      	Not equal:
        	            	expected: "INPUT_CONFIG_OK\n"
        	            	actual  : "INPUT_CONFIG_OK\n\nExit code: 1\n"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2 +2,3 @@

        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
        	Messages:   	bundle/invariant/no_drift/output.txt vs /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundleinvariantno_driftDATABRICKS_BUNDLE_ENGINE=di2526780256/001/output.txt
    acceptance_test.go:942:
        LOG.config: bundle:
        LOG.config:   name: test-bundle-q74yvfo34ffezmspxodeoenate
        LOG.config:
        LOG.config: resources:
        LOG.config:   alerts:
        LOG.config:     foo:
        LOG.config:       warehouse_id: 8ec9edc1-db0c-40df-af8d-7580020fe61e
        LOG.config:       display_name: test-alert-q74yvfo34ffezmspxodeoenate
        LOG.config:       file_path: ./alert.dbalert.json
        LOG.config:       permissions:
        LOG.config:         - level: CAN_MANAGE
        LOG.config:           group_name: users
    acceptance_test.go:942: LOG.cp:
    acceptance_test.go:942:
        LOG.deploy:
        LOG.deploy: >>> /Users/denis.bilenko/work/cli-trees/local-only/acceptance/build/darwin_arm64/1.6.0/databricks bundle deploy
        LOG.deploy: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/test-bundle-q74yvfo34ffezmspxodeoenate/default/files...
        LOG.deploy: Deploying resources...
        LOG.deploy: Updating deployment state...
        LOG.deploy: Deployment complete!
    acceptance_test.go:942:
        LOG.destroy:
        LOG.destroy: >>> /Users/denis.bilenko/work/cli-trees/local-only/acceptance/build/darwin_arm64/1.6.0/databricks bundle destroy --auto-approve
        LOG.destroy: The following resources will be deleted:
        LOG.destroy:   delete resources.alerts.foo
        LOG.destroy:
        LOG.destroy: All files and directories at the following location will be deleted: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-q74yvfo34ffezmspxodeoenate/default
        LOG.destroy:
        LOG.destroy: Deleting files...
        LOG.destroy: Destroy complete!
    acceptance_test.go:942: LOG.planjson:
    acceptance_test.go:942:
        LOG.validate:
        LOG.validate: >>> /Users/denis.bilenko/work/cli-trees/local-only/acceptance/build/darwin_arm64/1.6.0/databricks bundle validate
        LOG.validate: Name: test-bundle-q74yvfo34ffezmspxodeoenate
        LOG.validate: Target: default
        LOG.validate: Workspace:
        LOG.validate:   User: tester@databricks.com
        LOG.validate:   Path: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-q74yvfo34ffezmspxodeoenate/default
        LOG.validate:
        LOG.validate: Validation OK!
--- FAIL: TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN= (0.32s)
```

</details>

<details>
<summary>TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 ✅ | main (de465e09b) ❌ | latest (v1.6.0) ❌</summary>

**main (de465e09b):**
```
=== RUN   TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
=== PAUSE TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
=== CONT  TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
    acceptance_test.go:1083:
        	Error Trace:	/Users/denis.bilenko/work/cli-trees/local-only/libs/testdiff/testdiff.go:22
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:1083
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:915
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:515
        	Error:      	Not equal:
        	            	expected: "INPUT_CONFIG_OK\n"
        	            	actual  : "INPUT_CONFIG_OK\n\nExit code: 1\n"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2 +2,3 @@

        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
        	Messages:   	bundle/invariant/no_drift/output.txt vs /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundleinvariantno_driftDATABRICKS_BUNDLE_ENGINE=di1652478110/001/output.txt
    acceptance_test.go:942:
        LOG.config: bundle:
        LOG.config:   name: test-bundle-yjzfni652vbtvi5ymltuu4jisu
        LOG.config:
        LOG.config: resources:
        LOG.config:   alerts:
        LOG.config:     foo:
        LOG.config:       warehouse_id: 8ec9edc1-db0c-40df-af8d-7580020fe61e
        LOG.config:       display_name: test-alert-yjzfni652vbtvi5ymltuu4jisu
        LOG.config:       file_path: ./alert.dbalert.json
        LOG.config:       permissions:
        LOG.config:         - level: CAN_MANAGE
        LOG.config:           group_name: users
    acceptance_test.go:942: LOG.cp:
    acceptance_test.go:942:
        LOG.deploy:
        LOG.deploy: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle deploy --plan plan.json
        LOG.deploy: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/test-bundle-yjzfni652vbtvi5ymltuu4jisu/default/files...
        LOG.deploy: Deploying resources...
        LOG.deploy: Updating deployment state...
        LOG.deploy: Deployment complete!
    acceptance_test.go:942:
        LOG.destroy:
        LOG.destroy: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle destroy --auto-approve
        LOG.destroy: The following resources will be deleted:
        LOG.destroy:   delete resources.alerts.foo
        LOG.destroy:
        LOG.destroy: All files and directories at the following location will be deleted: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-yjzfni652vbtvi5ymltuu4jisu/default
        LOG.destroy:
        LOG.destroy: Deleting files...
        LOG.destroy: Destroy complete!
    acceptance_test.go:942: LOG.planjson:
    acceptance_test.go:942:
        LOG.validate:
        LOG.validate: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle validate
        LOG.validate: Name: test-bundle-yjzfni652vbtvi5ymltuu4jisu
        LOG.validate: Target: default
        LOG.validate: Workspace:
        LOG.validate:   User: tester@databricks.com
        LOG.validate:   Path: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-yjzfni652vbtvi5ymltuu4jisu/default
        LOG.validate:
        LOG.validate: Validation OK!
--- FAIL: TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 (0.32s)
```

**latest (v1.6.0):**
```
=== RUN   TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
=== PAUSE TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
=== CONT  TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
    acceptance_test.go:1083:
        	Error Trace:	/Users/denis.bilenko/work/cli-trees/local-only/libs/testdiff/testdiff.go:22
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:1083
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:915
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:515
        	Error:      	Not equal:
        	            	expected: "INPUT_CONFIG_OK\n"
        	            	actual  : "INPUT_CONFIG_OK\n\nExit code: 1\n"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2 +2,3 @@

        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1
        	Messages:   	bundle/invariant/no_drift/output.txt vs /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundleinvariantno_driftDATABRICKS_BUNDLE_ENGINE=di1892342805/001/output.txt
    acceptance_test.go:942:
        LOG.config: bundle:
        LOG.config:   name: test-bundle-ly7ipbof5naa5eogrk43vhpxay
        LOG.config:
        LOG.config: resources:
        LOG.config:   alerts:
        LOG.config:     foo:
        LOG.config:       warehouse_id: 8ec9edc1-db0c-40df-af8d-7580020fe61e
        LOG.config:       display_name: test-alert-ly7ipbof5naa5eogrk43vhpxay
        LOG.config:       file_path: ./alert.dbalert.json
        LOG.config:       permissions:
        LOG.config:         - level: CAN_MANAGE
        LOG.config:           group_name: users
    acceptance_test.go:942: LOG.cp:
    acceptance_test.go:942:
        LOG.deploy:
        LOG.deploy: >>> /Users/denis.bilenko/work/cli-trees/local-only/acceptance/build/darwin_arm64/1.6.0/databricks bundle deploy --plan plan.json
        LOG.deploy: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/test-bundle-ly7ipbof5naa5eogrk43vhpxay/default/files...
        LOG.deploy: Deploying resources...
        LOG.deploy: Updating deployment state...
        LOG.deploy: Deployment complete!
    acceptance_test.go:942:
        LOG.destroy:
        LOG.destroy: >>> /Users/denis.bilenko/work/cli-trees/local-only/acceptance/build/darwin_arm64/1.6.0/databricks bundle destroy --auto-approve
        LOG.destroy: The following resources will be deleted:
        LOG.destroy:   delete resources.alerts.foo
        LOG.destroy:
        LOG.destroy: All files and directories at the following location will be deleted: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-ly7ipbof5naa5eogrk43vhpxay/default
        LOG.destroy:
        LOG.destroy: Deleting files...
        LOG.destroy: Destroy complete!
    acceptance_test.go:942: LOG.planjson:
    acceptance_test.go:942:
        LOG.validate:
        LOG.validate: >>> /Users/denis.bilenko/work/cli-trees/local-only/acceptance/build/darwin_arm64/1.6.0/databricks bundle validate
        LOG.validate: Name: test-bundle-ly7ipbof5naa5eogrk43vhpxay
        LOG.validate: Target: default
        LOG.validate: Workspace:
        LOG.validate:   User: tester@databricks.com
        LOG.validate:   Path: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-ly7ipbof5naa5eogrk43vhpxay/default
        LOG.validate:
        LOG.validate: Validation OK!
--- FAIL: TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl/LOCAL_DIFF=--local/READPLAN=1 (0.32s)
```

</details>

<details>
<summary>TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN= ✅ | main (de465e09b) ❌ | latest (v1.6.0) ❌</summary>

**main (de465e09b):**
```
=== RUN   TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== PAUSE TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== CONT  TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
    acceptance_test.go:1083:
        	Error Trace:	/Users/denis.bilenko/work/cli-trees/local-only/libs/testdiff/testdiff.go:22
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:1083
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:915
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:515
        	Error:      	Not equal:
        	            	expected: "INPUT_CONFIG_OK\n"
        	            	actual  : "INPUT_CONFIG_OK\n\nExit code: 1\n"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2 +2,3 @@

        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
        	Messages:   	bundle/invariant/no_drift/output.txt vs /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundleinvariantno_driftDATABRICKS_BUNDLE_ENGINE=di1994182820/001/output.txt
    acceptance_test.go:942:
        LOG.config: bundle:
        LOG.config:   name: test-bundle-42b7orzkifflve5iq6gr7qgpnu
        LOG.config:
        LOG.config: resources:
        LOG.config:   apps:
        LOG.config:     foo:
        LOG.config:       name: app-42b7orzkifflve5iq6gr7qgpnu
        LOG.config:       source_code_path: ./app
        LOG.config:       permissions:
        LOG.config:         - level: CAN_USE
        LOG.config:           group_name: users
    acceptance_test.go:942: LOG.cp:
    acceptance_test.go:942:
        LOG.deploy:
        LOG.deploy: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle deploy
        LOG.deploy: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/test-bundle-42b7orzkifflve5iq6gr7qgpnu/default/files...
        LOG.deploy: Deploying resources...
        LOG.deploy: Updating deployment state...
        LOG.deploy: Deployment complete!
    acceptance_test.go:942:
        LOG.destroy:
        LOG.destroy: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle destroy --auto-approve
        LOG.destroy: The following resources will be deleted:
        LOG.destroy:   delete resources.apps.foo
        LOG.destroy:
        LOG.destroy: All files and directories at the following location will be deleted: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-42b7orzkifflve5iq6gr7qgpnu/default
        LOG.destroy:
        LOG.destroy: Deleting files...
        LOG.destroy: Destroy complete!
    acceptance_test.go:942: LOG.planjson:
    acceptance_test.go:942:
        LOG.validate:
        LOG.validate: >>> /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/regression_main_cli_zcw9ioq8/src/databricks bundle validate
        LOG.validate: Name: test-bundle-42b7orzkifflve5iq6gr7qgpnu
        LOG.validate: Target: default
        LOG.validate: Workspace:
        LOG.validate:   User: tester@databricks.com
        LOG.validate:   Path: /Workspace/Users/tester@databricks.com/.bundle/test-bundle-42b7orzkifflve5iq6gr7qgpnu/default
        LOG.validate:
        LOG.validate: Validation OK!
--- FAIL: TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN= (0.32s)
```

**latest (v1.6.0):**
```
=== RUN   TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== PAUSE TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
=== CONT  TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
    acceptance_test.go:1083:
        	Error Trace:	/Users/denis.bilenko/work/cli-trees/local-only/libs/testdiff/testdiff.go:22
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:1083
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:915
        	            				/Users/denis.bilenko/work/cli-trees/local-only/acceptance/acceptance_test.go:515
        	Error:      	Not equal:
        	            	expected: "INPUT_CONFIG_OK\n"
        	            	actual  : "INPUT_CONFIG_OK\n\nExit code: 1\n"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2 +2,3 @@

        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=app.yml.tmpl/LOCAL_DIFF=--local/READPLAN=
        	Messages:   	bundle/invariant/no_drift/output.txt vs /var/folders/5y/9kkdnjw91p11vsqwk0cvmk200000gp/T/TestAcceptbundleinvariantno_driftDATABRICKS_BUNDLE_ENGINE=di992411277/001/output.txt
    acceptance_test.go:942:
        LOG.config: bundle:
       …
In --local mode the per-resource remote read is skipped. Previously this left
the remote comparison value nil, so state-only fields reconciled via
OverrideChangeDesc (dashboard/genie etag, vector_search_index endpoint_uuid)
read as spurious drift. Treat the saved state as the remote stand-in: it is our
last recorded snapshot of remote, so drift is computed purely from saved-state
vs config and these fields reconcile against their saved value.

VectorSearchIndex.OverrideChangeDesc now reads change.Remote (equal to the raw
remote's EndpointUuid) instead of the raw remote param, which is nil in --local.

Drops the three no_drift EnvMatrixExclude entries that worked around this, and
reverts the --local matrix on schemas/drift/managed_properties (its subject is a
remote-only managed-properties map that has no local stand-in, so it is a
genuine bad fit for --local).

Co-authored-by: Isaac
The hook dereferenced its raw remote *AppRemote param, but calladapt
delivers a typed nil when the remote read is skipped (--local) or the
resource does not exist remotely. Read change.Remote instead, matching
the pattern used by vector_search_index.

Co-authored-by: Isaac
Every row now passes a typed-nil raw remote param, so the nil-safety
guarantee is exercised on every case rather than a dedicated subtest.

Co-authored-by: Isaac
Introduce deployplan.PlanMode enum (Full, Local, Offline) and thread it
through the planner and CLI. --local becomes --plan-mode=local; Offline
is reserved for a follow-up. Bundle.Local becomes Bundle.PlanMode, and
the local_used telemetry key becomes plan_mode_used_<mode>.

Co-authored-by: Isaac
Two fixes from the cursor-agent review:

1. In --plan-mode=local, entry.RemoteState was being set to savedState
   (state type, e.g. *AppState). Apply-time consumers like
   remoteIsStarted type-assert to the remote type (*AppRemote) and
   silently returned false, which made manageLifecycle skip a Stop when
   config toggled lifecycle.started true → false. Leave entry.RemoteState
   nil in local mode; classification still uses savedState via the local
   remoteStateComparable variable that feeds change.Remote.

2. --plan-mode=offline was accepted at flag-parse but not wired: a
   reference to a remote-only field on an unchanged target hit an
   internal error in LookupReferencePreDeploy. Reject the value at parse
   time until Offline semantics are implemented. SkipsRemoteReads()
   narrowed to Local only.

acc: local/rejected covers the offline rejection and unknown values.
acc: local/basic output.txt regenerated (remote_state no longer present
in local-mode plan JSON).

Co-authored-by: Isaac
…tate (RemoteType)

Fixes three apply-time bugs in --plan-mode=local where entry.RemoteState
was left nil to avoid type confusion:

  1. grants.go removedGrantPrincipals returned nil, so config that removed
     a grant silently kept it in place.
  2. cluster/sql_warehouse lifecycle: remoteXIsRunning(entry) returned
     false, causing Start/Stop decisions to be wrong and WaitAfterUpdate
     to poll for a state that never happens.
  3. app.go manageLifecycle called with alreadyStarted=false regardless of
     the real remote lifecycle state.

Design:

- PlanEntry.PriorState (new, StateType) — always the last saved local
  state. Populated in every mode. Consumers that read state-shaped fields
  (grants principals, dashboard/genie etag) read this via RemoteOrPrior.
- PlanEntry.RemoteState (existing, RemoteType) — a fresh remote read.
  Nil in --plan-mode=local. Consumers that read remote-only fields
  (cluster.State, app.ComputeStatus) read this; the reasonable behavior
  on nil is to skip whatever depends on live status.
- PlanEntry.RemoteOrPrior(adapter) — helper preferring the freshly-
  remapped RemoteState, falling back to PriorState. Uses a small
  RemapStater interface to keep bundle/deployplan free of dresources.

Consumer changes:

- grants.go: read prior grants from RemoteState with PriorState fallback.
  Local-mode grants now correctly remove principals absent from config.
- bind.go: etag lookup falls back to PriorState (safe: dashboard/genie
  have StateType == RemoteType).
- cluster.go, app.go, sql_warehouse.go: DoUpdate skips lifecycle
  management when entry.RemoteState is nil. cluster/sql_warehouse
  WaitAfterUpdate skips its poll as well; app has no separate WaitAfter.
- WaitAfterUpdate signature bumped to include *PlanEntry (cluster,
  sql_warehouse, model_serving_endpoint).
- model.go: ModelId carryforward stays on RemoteState (only place it
  lives); documented that same-run refs to model_id resolve to empty in
  --plan-mode=local.

Tests:

- New acceptance/bundle/local/lifecycle-skip: cluster with lifecycle
  toggle; local-mode deploy issues zero /clusters requests.
- New acceptance/bundle/local/grants-remove: schema grants with a
  principal removed from config; local-mode deploy correctly revokes it.
- All out.plan.*.json regenerated: full-mode plans now include both
  prior_state and remote_state; local-mode plans include only prior_state.

Co-authored-by: Isaac
…sing

CalculatePlan was falling back to PriorState via RemoteOrPrior when the
remote read returned missing, which caused resources that were trashed
out-of-band to be classified as if they still existed remotely (etag
change was Skip instead of Update, dashboard delete-trashed-out-of-band
regressed). Compute remoteStateComparable explicitly per mode: skip-mode
uses savedState directly; full mode uses RemapState(remoteRead) or nil.
RemoteOrPrior remains for apply-time consumers (grants/bind) where the
"fresh remote or fall back to saved" semantics are correct.

acc: switch bundle summary+jq to read_id.py in local/basic and
local/references (shorter and adds a [BAR_ID] repl).

acc: use "# TO_DELETE" markers + grep -v in local/grants-remove instead
of a fragile python regex on databricks.yml.

Co-authored-by: Isaac
…tion

I briefly enabled --plan-mode=offline during the review-cursor cycle and
the terraform variant of local/rejected still had the transient output.

Co-authored-by: Isaac
PriorState is the state-shaped stand-in for RemoteState. In full mode
every resource reaching Update has RemoteState populated by construction
(Create is picked when remote is missing), so PriorState is unused. Drop
it there to keep the plan JSON compact — regen shrinks by ~2.5k lines
across the acceptance tree.

Co-authored-by: Isaac
… is nil

Prior code returned a *MlflowModelRemote with empty model_id in local mode
(because entry.RemoteState was nil, so the carry-forward yielded ""). But
refreshRemoteState short-circuits when the returned remote is non-nil, so
downstream references to ${resources.models.foo.model_id} resolved to
empty. Return nil like DoCreate does: the engine will DoRead to populate
the full state, including model_id.

Also drop the unused RemoteOrPrior helper (and RemapStater interface) —
the two consumers that would have used it inline the fallback directly.

Co-authored-by: Isaac
@denik
denik force-pushed the denik/local-only branch from 3a88436 to e1f4064 Compare July 22, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants